namespace NetFx.MSIL
{
  using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Reflection;
  using System.Reflection.Emit;

  [Flags]
  public enum MethodAttribute:byte
  {
    DEFAULT = 0x0, // default calling convention
    C = 0x1, // C calling convention
    STDCALL = 0x2, // Stdcall calling convention
    THISCALL = 0x3, // thiscall  calling convention
    FASTCALL = 0x4, // fastcall calling convention
    VARARG = 0x5, // vararg calling convention
    GENERIC = 0x10, // used to indicate that the method has one or more generic parameters.
    HASTHIS = 0x20,  // used to encode the keyword instance in the calling convention
    EXPLICITTHIS = 0x40, // used to encode the keyword explicit in the calling convention
  }

  public class MethodSignature : Signature
  {
    #region Statics
    public static MethodSignature of(MethodAttribute attribute, List<ParameterSignature> parameters, ReturnTypeSignature returnType)
    {
      return new MethodSignature(attribute, parameters, returnType);
    }
    public static MethodSignature of(MethodAttribute attribute, List<ParameterSignature> parameters, ReturnTypeSignature returnType, int genericParametersCount)
    {
      return new MethodSignature(attribute, parameters, returnType, genericParametersCount);
    }
    #endregion
    #region Fields
    protected List<ParameterSignature> parameters = null;
    protected ReturnTypeSignature returnType = null;
    protected int genericParametersCount = 0;
    protected MethodAttribute attribute = MethodAttribute.DEFAULT;
    #endregion
    public virtual MethodAttribute Attribute
    {
      get
      {
        return this.attribute;
      }
    }
    public virtual List<ParameterSignature> Parameters
    {
      get
      {
        return this.parameters;
      }
    }
    public virtual int ParamCount
    {
      get
      {
        return this.parameters != null ? this.parameters.Count : 0;
      }
    }
    public virtual int GenericParamCount
    {
      get
      {
        return this.genericParametersCount;
      }
    }
    public virtual ReturnTypeSignature ReturnType
    {
      get
      {
        return this.returnType;
      }
    }
    #region Properties
    #endregion
    #region Constructors
    public MethodSignature(MethodAttribute attribute, List<ParameterSignature> parameters, ReturnTypeSignature returnType)
      :this(attribute ,parameters,returnType,0)
    {
    }
    public MethodSignature(MethodAttribute attribute, List<ParameterSignature> parameters, ReturnTypeSignature returnType, int genericParametersCount)
    {
      this.attribute = attribute;
      this.parameters = parameters;
      this.returnType = returnType;
      this.genericParametersCount = genericParametersCount;
    }
    #endregion
    #region Methods
    #endregion
  }
}
